package middleware

import (
	"bytes"
	"fmt"
	"gitee.com/wuzheng0709/backend-gopkg/infrastructure/pkg/code"
	signature2 "gitee.com/wuzheng0709/backend-gopkg/infrastructure/pkg/gin/middleware/signature"
	"github.com/gin-gonic/gin"
	"io"
	"net/http"
	"net/url"
	"sort"
	"strings"
)

// NoMethodHandler 未找到请求方法的处理函数
func NoMethodHandler() gin.HandlerFunc {
	return func(c *gin.Context) {
		c.JSON(400, gin.H{"code": code.NoMethod_ERR, "msg": "方法不被允许"})
		c.Abort()
	}
}

// NoRouteHandler 未找到请求路由的处理函数
func NoRouteHandler() gin.HandlerFunc {
	return func(c *gin.Context) {
		c.JSON(404, gin.H{"code": code.NoMethod_ERR, "msg": "未找到请求路由的处理函数"})
		c.Abort()
	}
}

// SkipperFunc 定义中间件跳过函数
type SkipperFunc func(*gin.Context) bool

// AllowPathPrefixSkipper 检查请求路径是否包含指定的前缀，如果包含则跳过
func AllowPathPrefixSkipper(prefixes ...string) SkipperFunc {
	return func(c *gin.Context) bool {
		path := c.Request.URL.Path
		pathLen := len(path)
		for _, p := range prefixes {
			if pl := len(p); pathLen >= pl && path[:pl] == p {
				return true
			}
		}
		return false
	}
}

//var Opt Option

//type Option struct {
//	Headers string
//
//	AccessKey string
//	Secret    string
//
//	Version   string
//	Algorithm string
//}

// AllowPathPrefixNoSkipper 检查请求路径是否包含指定的前缀，如果包含则不跳过
func AllowPathPrefixNoSkipper(prefixes ...string) SkipperFunc {
	return func(c *gin.Context) bool {
		path := c.Request.URL.Path
		pathLen := len(path)

		for _, p := range prefixes {
			if pl := len(p); pathLen >= pl && path[:pl] == p {
				return false
			}
		}
		return true
	}
}

// SignMiddleware 生成签名中间件函数
// headerKeys 不同接口对应不同请求头，需查看 财务云 接口文件进行传输
func SignMiddleware(headerKeys []string, urlStr string) gin.HandlerFunc {
	return func(c *gin.Context) {
		method := c.Request.Method
		queryParams := make([]signature2.RequestParams, 0, len(c.Request.URL.Query()))
		for key, values := range c.Request.URL.Query() {
			for _, value := range values {
				queryParams = append(queryParams, signature2.RequestParams{
					Key:   key,
					Value: url.QueryEscape(value),
				})
			}
		}
		// 对查询参数进行排序
		sort.Slice(queryParams, func(i, j int) bool {
			var status bool
			queryParams[i].Value = strings.Replace(url.QueryEscape(queryParams[i].Value), "+", "%20", -1)
			queryParams[j].Value = strings.Replace(url.QueryEscape(queryParams[j].Value), "+", "%20", -1)
			if queryParams[i].Key == queryParams[j].Key {
				status = queryParams[i].Value < queryParams[j].Value
				return status
			}
			status = queryParams[i].Key < queryParams[j].Key
			return status
		})

		var headerParams []signature2.RequestHeaders
		for _, key := range headerKeys {
			headerParams = append(headerParams, signature2.RequestHeaders{
				Key:   key,
				Value: c.Request.Header.Get(key),
			})
		}
		// 对请求头参数进行排序
		sort.Slice(headerParams, func(i, j int) bool {
			if headerParams[i].Key == headerParams[j].Key {
				return headerParams[i].Value < headerParams[j].Value
			}

			return headerParams[i].Key < headerParams[j].Key
		})
		bodyBytes, err := io.ReadAll(c.Request.Body)
		c.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
		if err != nil {
			c.JSON(http.StatusBadRequest, gin.H{
				"error": err.Error(),
			})
		}
		// 创建签名对象
		sign := signature2.NewDefaultRequestSignature(method, urlStr, queryParams, headerParams, bodyBytes)
		authStr := sign.GenAuthorization()
		fmt.Println("密钥", authStr)
		c.Request.Header.Set("Authorization", authStr)
		c.Next()
	}
}

// SignMiddleware 生成签名中间件函数
// headerKeys 不同接口对应不同请求头，需查看 财务云 接口文件进行传输
func SignMiddlewareV2(headerKeys []string, bodyBytes []byte) gin.HandlerFunc {
	return func(c *gin.Context) {
		method := c.Request.Method
		queryParams := make([]signature2.RequestParams, 0, len(c.Request.URL.Query()))
		for key, values := range c.Request.URL.Query() {
			for _, value := range values {
				queryParams = append(queryParams, signature2.RequestParams{
					Key:   key,
					Value: url.QueryEscape(value),
				})
			}
		}
		// 对查询参数进行排序
		sort.Slice(queryParams, func(i, j int) bool {
			var status bool
			queryParams[i].Value = strings.Replace(url.QueryEscape(queryParams[i].Value), "+", "%20", -1)
			queryParams[j].Value = strings.Replace(url.QueryEscape(queryParams[j].Value), "+", "%20", -1)
			if queryParams[i].Key == queryParams[j].Key {
				status = queryParams[i].Value < queryParams[j].Value
				return status
			}
			status = queryParams[i].Key < queryParams[j].Key
			return status
		})

		var headerParams []signature2.RequestHeaders
		for _, key := range headerKeys {
			headerParams = append(headerParams, signature2.RequestHeaders{
				Key:   key,
				Value: c.Request.Header.Get(key),
			})
		}
		// 对请求头参数进行排序
		sort.Slice(headerParams, func(i, j int) bool {
			if headerParams[i].Key == headerParams[j].Key {
				return headerParams[i].Value < headerParams[j].Value
			}

			return headerParams[i].Key < headerParams[j].Key
		})
		//bodyBytes, err := io.ReadAll(c.Request.Body)
		//c.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
		//if err != nil {
		//	c.JSON(http.StatusBadRequest, gin.H{
		//		"error": err.Error(),
		//	})
		//}
		// 创建签名对象
		sign := signature2.NewDefaultRequestSignature(method, c.Request.URL.Path, queryParams, headerParams, bodyBytes)
		authStr := sign.GenAuthorization()
		fmt.Println("密钥", authStr)
		c.Request.Header.Add("Authorization", authStr)
		c.Next()
	}
}
